<html>
<head>
	<meta http-equiv='Content-Type' content='text/html;charset=utf-8'/>
    <meta http-equiv="X-UA-Compatible" content="chrome=1,IE=edge" />
	<title>Using RenderedTexture for Mirror Effects</title>
    <script type="text/javascript" src="../../../../x3dom-include.js"></script>
    
    <script>
        var x3domRuntime;
        
        var defaultUpVec = new x3dom.fields.SFVec3f(0, 1, 0);
        
        var makeLookAt = function(eye, at, up)
        {
            var view = at.subtract(eye).normalize();
            up = up.normalize();
            var right = view.cross(up);
            var newUp = right.cross(view);
            var lookAt = x3dom.fields.SFMatrix4f.identity();
            lookAt.setValue(right, newUp, view.negate(), new x3dom.fields.SFVec3f(0.0, 0.0, 0.0));
            lookAt = lookAt.transpose();
            lookAt = lookAt.mult(x3dom.fields.SFMatrix4f.translation(eye.negate()));            
            return lookAt;
        }        
        
        var frameStart = function()
        {               
            //assume square mirror with an extent of mirrorSize along each axis
            var mirrorSize = 12;
        
            var ms = document.getElementById('myMirrorShape');
            var mv = document.getElementById('myMirrorTextureViewPoint');            
            
            //compute transformations related to local mirror space
            var mirrorToWorldMat = ms._x3domNode.getCurrentTransform();
           //var worldToMirrorMat = mirrorToWorldMat.inverse();
            var mirrorPos    = mirrorToWorldMat.multMatrixPnt(new x3dom.fields.SFVec3f(0, 0, 0));
            var mirrorNormal = mirrorToWorldMat.multMatrixVec(new x3dom.fields.SFVec3f( 0, 0, 1));
            var mirrorUp     = mirrorToWorldMat.multMatrixVec(new x3dom.fields.SFVec3f( 0, 1, 0));
            var mirrorRight  = mirrorToWorldMat.multMatrixVec(new x3dom.fields.SFVec3f(-1, 0, 0));
            
            //transform view vector and view point to local mirror space            
            var viewMatInv = x3domRuntime.viewMatrix().inverse();
            var vPos = viewMatInv.multMatrixPnt(new x3dom.fields.SFVec3f(0, 0, 0));
                //vPos = worldToMirrorMat.multMatrixPnt(vPos);                
           
            var vVecNor = vPos.subtract(mirrorPos);            
            
            //compute distance between viewer and mirror
            var viewDist = vVecNor.length(); 
            vVecNor      = vVecNor.normalize(); 
            
            //reflect view vector on mirror normal
            var reflect = mirrorNormal.multiply(2 * vVecNor.dot(mirrorNormal)).subtract(vVecNor);
            
            //update mirror's camera settings
            var mirrorEyeOffset = reflect.multiply(viewDist);
            var mirrorEye = mirrorPos.subtract(mirrorEyeOffset);           
            
            //setup view matrix
            var vMatMirr  = makeLookAt(mirrorEye, mirrorEye.add(mirrorNormal), defaultUpVec);            
            mv._x3domNode._viewMatrix = vMatMirr;          
            
            //setup perspective frustum parameters (left, right, bottom, top, near, far)
            var sH = 0.5 * mirrorSize;
            
            var near  =  mirrorNormal.dot(mirrorEyeOffset);
            var left  =  mirrorRight.dot(mirrorEyeOffset) - sH;
            var right =  mirrorRight.dot(mirrorEyeOffset) + sH;
            var bottom =  mirrorUp.dot(mirrorEyeOffset)   - sH;
            var top    =  mirrorUp.dot(mirrorEyeOffset)   + sH;
                        
            var pMatMirr  = x3dom.fields.SFMatrix4f.perspectiveFrustum( left, right, 
                                                                        bottom, top,       
                                                                        near,    10000.0);
            mv._x3domNode._projMatrix = pMatMirr;
        };
        
        document.onload = function(){
            x3domRuntime = document.getElementById('myX3DWorld').runtime;
            x3domRuntime.enterFrame = frameStart;
        };
    </script>
</head>
<body>
    
	<div style="width:100%; height:800px;">
        <X3D id='myX3DWorld' width="800px" height="600px">
          <Scene DEF='scene'>
            <Viewpoint id='view1' position="20.85148 2.26663 27.32183" orientation="-0.21193 0.97725 0.00820 0.69814"></Viewpoint>
            
            <Background skyColor='1 1 1' groundColor='1 1 1'></Background>
            
            <group DEF='MIRROR_SCENE'>
                <NavigationInfo headLight="false" ></NavigationInfo>
                <DirectionalLight direction=' 0.7  0.2 -0.5' intensity='0.85' color='1 1 1'></DirectionalLight>
                <DirectionalLight direction='-0.7 -0.2  0.5' intensity='0.6'  color='1 1 0.8'></DirectionalLight>
                                       
                <Transform translation='0 -8 8' > 
                
                    <transform DEF='Ground'>
                        <shape DEF='SP_3'>
                        <appearance DEF='_03_-_Default'>
                          <imageTexture crossOrigin='anonymous' url='"./ground.jpg"'></imageTexture>
                        </appearance>
                        <binaryGeometry DEF='Ground_0-GEOMETRY' solid='true' vertexCount='4' primType='"TRIANGLESTRIP"' size='50 0 50' index='./Ground_0-GEOMETRY_indexBinary.bin' coord='./Ground_0-GEOMETRY_coordNormalBinary.bin+8' texCoord='./Ground_0-GEOMETRY_texCoordBinary.bin+4' coordType='Uint16' texCoordType='Uint16' normalAsSphericalCoordinates='true'></binaryGeometry>
                        </shape>
                        </transform>
                        <transform DEF='Building' translation='1.7027 0.905127 -0.364374'>
                        <shape DEF='SP_4'>
                        <appearance DEF='_02_-_Default'>
                          <imageTexture crossOrigin='anonymous' url='"./building.png"'></imageTexture>
                        </appearance>
                        <binaryGeometry DEF='Building_0-GEOMETRY' solid='false' vertexCount='15062 87477' primType='"TRIANGLESTRIP" "TRIANGLES"' position='-1.70269489288 2.45732712746 0.364373683929' size='24.8268699646 6.68882608414 14.8100013733' coord='./Building_0-GEOMETRY_coordNormalBinary.bin+8' texCoord='./Building_0-GEOMETRY_texCoordBinary.bin+4' coordType='Uint16' texCoordType='Uint16' normalAsSphericalCoordinates='true'></binaryGeometry>
                        </shape>
                        <shape DEF='SP_7'>
                        <appearance USE='_02_-_Default'></appearance>
                        <binaryGeometry DEF='Building_1-GEOMETRY' solid='false' vertexCount='1322 11937' primType='"TRIANGLESTRIP" "TRIANGLES"' position='-1.70269489288 2.44684505463 0.362128734589' size='24.8268699646 6.7097902298 14.6059093475' index='./Building_1-GEOMETRY_indexBinary.bin' coord='./Building_1-GEOMETRY_coordNormalBinary.bin+8' texCoord='./Building_1-GEOMETRY_texCoordBinary.bin+4' coordType='Uint16' texCoordType='Uint16' normalAsSphericalCoordinates='true'></binaryGeometry>
                        </shape>
                        <shape DEF='SP_0'>
                        <appearance USE='_02_-_Default'></appearance>
                        <binaryGeometry DEF='Building_2-GEOMETRY' solid='false' vertexCount='595 6036' primType='"TRIANGLESTRIP" "TRIANGLES"' position='-1.94029140472 2.24684500694 0.214373588562' size='24.3516769409 6.30979013443 14.3099994659' index='./Building_2-GEOMETRY_indexBinary.bin' coord='./Building_2-GEOMETRY_coordNormalBinary.bin+8' texCoord='./Building_2-GEOMETRY_texCoordBinary.bin+4' coordType='Uint16' texCoordType='Uint16' normalAsSphericalCoordinates='true'></binaryGeometry>
                        </shape>
                        <shape DEF='SP_2'>
                        <appearance USE='_02_-_Default'></appearance>
                        <binaryGeometry DEF='Building_3-GEOMETRY' solid='false' vertexCount='320 363' primType='"TRIANGLESTRIP" "TRIANGLES"' position='-1.60769557953 1.8018450737 0.0456223487854' size='24.6368675232 5.41979026794 13.39249897' index='./Building_3-GEOMETRY_indexBinary.bin' coord='./Building_3-GEOMETRY_coordNormalBinary.bin+8' texCoord='./Building_3-GEOMETRY_texCoordBinary.bin+4' coordType='Uint16' texCoordType='Uint16' normalAsSphericalCoordinates='true'></binaryGeometry>
                        </shape>
                        <shape DEF='SP_5'>
                        <appearance USE='_02_-_Default'></appearance>
                        <binaryGeometry DEF='Building_4-GEOMETRY' solid='false' vertexCount='980 11733' primType='"TRIANGLESTRIP" "TRIANGLES"' position='-1.35274505615 1.83184552193 0.164373874664' size='24.1269683838 5.4797911644 13.2100000381' index='./Building_4-GEOMETRY_indexBinary.bin' coord='./Building_4-GEOMETRY_coordNormalBinary.bin+8' texCoord='./Building_4-GEOMETRY_texCoordBinary.bin+4' coordType='Uint16' texCoordType='Uint16' normalAsSphericalCoordinates='true'></binaryGeometry>
                        </shape>
                        <shape DEF='SP_6'>
                        <appearance USE='_02_-_Default'></appearance>
                        <binaryGeometry DEF='Building_5-GEOMETRY' solid='false' vertexCount='218 1836' primType='"TRIANGLESTRIP" "TRIANGLES"' position='-0.290195465088 1.831594944 1.55937314034' size='22.0018692017 5.47929000854 10.329000473' index='./Building_5-GEOMETRY_indexBinary.bin' coord='./Building_5-GEOMETRY_coordNormalBinary.bin+8' texCoord='./Building_5-GEOMETRY_texCoordBinary.bin+4' coordType='Uint16' texCoordType='Uint16' normalAsSphericalCoordinates='true'></binaryGeometry>
                        </shape>
                        <shape DEF='SP_1'>
                        <appearance USE='_02_-_Default'></appearance>
                        <binaryGeometry DEF='Building_6-GEOMETRY' solid='false' vertexCount='120 1029' primType='"TRIANGLESTRIP" "TRIANGLES"' position='4.07137012482 0.48423999548 -0.235626220703' size='6.06500005722 2.16499996185 12.4099998474' index='./Building_6-GEOMETRY_indexBinary.bin' coord='./Building_6-GEOMETRY_coordNormalBinary.bin+8' texCoord='./Building_6-GEOMETRY_texCoordBinary.bin+4' coordType='Uint16' texCoordType='Uint16' normalAsSphericalCoordinates='true'></binaryGeometry>
                        </shape>
                    </transform>
                
                </transform>
                 
            </group>
            <Transform DEF='mirrorTrans' translation='2 0 -12' rotation='1 1 0 0.3'>
                <Transform translation='0.0 0.0 -0.3' scale='7.0 7.0 0.2'>
                    <Shape>
                        <Appearance><Material diffuseColor='0.8 0.75 0.6'></Material></Appearance>
                        <Box></Box>
                    </Shape>
                </Transform>
                <Shape id='myMirrorShape' DEF='myMirrorShape'>
                  <IndexedFaceSet solid="false" coordIndex='0 1 2 3 -1'>
                    <Coordinate point='-6 -6 0, 6 -6 0, 6 6 0, -6 6 0'></Coordinate>
                    <TextureCoordinate point='1 1, 0 1, 0 0, 1 0'></TextureCoordinate>
                  </IndexedFaceSet>
                  <Appearance DEF='rtApp'>
                    <RenderedTexture id='myRenderedTexture' update='always' dimensions='512 512 4' 
                                     repeatS='false' repeatT='false' >
                      <!--Shape USE='myMirrorShape' containerField='excludeNodes' ></Shape-->                      
                      <Background skyColor='1 1 1' groundColor='1 1 1' containerField='background'></Background>
                      <Viewpoint id='myMirrorTextureViewPoint' zNear="0.1" zFar="1000" containerField='viewpoint' ></Viewpoint>
                      <Group USE='MIRROR_SCENE'>                         
                      </Group>
                    </RenderedTexture>
                  </Appearance>
                </Shape>  
            </Transform>

          </Scene>
        </X3D>
	</div>
  </body>
</html>
